<template>
  <q-page class="q-pa-md">
    <div class="q-pb-md text-h5">{{ pageTitle }} <span class="text-subtitle1">集合验证的演示</span></div>
    <div class="shadow-2 q-pa-sm">
      <div class="row">
        <div class="col-12 q-gutter-sm">
          <q-btn color="primary" @click="touch">触碰</q-btn>
          <q-btn color="primary" @click="reset">重置</q-btn>
          <q-btn color="primary" @click="validate">验证</q-btn>
          <q-btn color="primary" @click="assignForm" no-caps>直接给$d.form赋值</q-btn>
          <q-btn color="negative" @click="clearLines">移除所有</q-btn>
          <q-btn color="primary" @click="childCompValTest">子组件验证测试</q-btn>
        </div>
      </div>
      <div class="row q-col-gutter-sm q-mt-sm">
        <div class="col-12 col-sm-6 col-md-4 col-lg-3">
          <q-icon color="red" name="fas fa-asterisk" size="10px" />
          <span>姓名</span>
          <q-input :error="v$.empName.$error" :error-message="e$(v$.empName.$errors)"
            :hide-bottom-space="true" dense :maxlength="30" outlined square stack-label
            v-model="$d.form.empName" autofocus></q-input>
        </div>
        <div class="col-12 col-sm-6 col-md-4 col-lg-3">
          <q-icon color="red" name="fas fa-asterisk" size="10px" />
          <span>年龄</span>
          <q-input :error="v$.empAge.$error" :error-message="e$(v$.empAge.$errors)"
            :hide-bottom-space="true" dense :maxlength="30" outlined square stack-label
            v-model="$d.form.empAge"></q-input>
        </div>
        <div class="col-12 col-sm-6 col-md-4 col-lg-3">
          <span>专业</span>
          <q-input :hide-bottom-space="true" dense :maxlength="30" outlined square stack-label
            v-model="$d.form.major"></q-input>
        </div>
        <div class="col-12">
          <table class="simple-static-table" style="min-width: 500px">
            <tr>
              <th>操作</th>
              <th>公司</th>
              <th>起始时间</th>
              <th>结束时间</th>
              <th>抬头</th>
            </tr>
            <tr v-for="(exp, idx) in $d.form.experiences" :key="idx">
              <td style="min-width: 102px">
                <q-btn color="negative" size="sm" @click="()=>removeLine(idx)">删除</q-btn>
                <q-btn class="q-ml-xs" color="primary" size="sm" @click="()=>blinkLineInput(idx)">闪烁</q-btn>
              </td>
              <td class="padding-slim">
                <easy-input :error="v$Lines[idx].company.$error" :error-message="e$(v$Lines[idx].company.$errors)"
                  v-model="exp.company" :bg-color="exp.inputBgColor"></easy-input>
              </td>
              <td class="padding-slim">
                <easy-input :error="v$Lines[idx].beginDt.$error" :error-message="e$(v$Lines[idx].beginDt.$errors)"
                  v-model="exp.beginDt" :append-icon-show="true" :use-date-picker="true" />
              </td>
              <td class="padding-slim">
                <easy-input :error="v$Lines[idx].endDt.$error" :error-message="e$(v$Lines[idx].endDt.$errors)"
                  v-model="exp.endDt" :append-icon-show="true" :use-date-picker="true" />
              </td>
              <td class="padding-slim">
                <easy-input v-model="exp.title"></easy-input>
              </td>
            </tr>
          </table>
        </div>
        <div class="col-12">
          <q-btn color="primary" icon="add" @click="addLine">增加明细</q-btn>
        </div>
      </div>
    </div>
    <ChildCompForValTest v-model="childComponentViewModel"></ChildCompForValTest>
  </q-page>
</template>

<script lang="ts" setup>

import {useTitleHelper} from '../../lib/hooks/titleHelper'
import {computed, reactive, ref} from 'vue'
import {useCollectionValHelper} from '../../lib/hooks/collectionValHelper'
import useVuelidate, {ValidationArgs} from '@vuelidate/core'
import EasyInput from '../../lib/components/EasyInput.vue'
import ChildCompForValTest from './ChildCompForValTest.vue'

const pageTitle = '集合验证DEMO'
useTitleHelper(pageTitle)

interface Experience {
  company: string
  beginDt: Date | string
  endDt: Date | string | null
  title: string | null
  inputBgColor?: string  //用于控制行的输入框闪烁
}

interface EmployeeInfo {
  empName: string
  empAge: number
  major: string | null
  experiences: Experience[]
}

const $d = reactive({
  form: {
    experiences: [
      {
        company: '上海大众',
        beginDt: '2003-06-02',
        endDt: '2003-10-17',
        title: '技工'
      },
      {
        company: '上海中和',
        beginDt: '2003-10-21',
        endDt: '2004-08-10',
        title: '程序员'
      }
    ] as Experience[]
  } as EmployeeInfo
})

const validators = $f.validators
const rules = {
  empName: {
    required: validators.required,
    len: validators.minLength(2)
  },
  empAge: {
    required: validators.required,
    greaterThan0: validators.greaterThan(0),
    int32: validators.int32,
    greaterEqualThan: validators.greaterEqualThan(0),
    lessEqualThan: validators.lessEqualThan(120)
  }
}

// 需要跟本行数据跨字段验证的时候，可以如此创建一个方法
const getRulesForLine: (line: Experience) => ValidationArgs = (line: Experience) => {
  return {
    company: {
      required: validators.required,
      len: validators.minLength(2)
    },
    beginDt: {
      required: validators.required,
      date: validators.date
    },
    endDt: {
      date: validators.date,
      greaterThan: validators.dateGreaterThan(computed(() => {
        return $f.fmt.dtFmtDateOnly(line.beginDt)
      }))
    }
  }
}

//主档的验证
const v$ = useVuelidate(rules, computed(() => $d.form), {$autoDirty: true, $scope: false})

const collValSuite = useCollectionValHelper(computed(() => $d.form.experiences), getRulesForLine)

const v$Lines = collValSuite.valObjs

const touch = function () {
  collValSuite.touch(v$.value)
}

const reset = function () {
  collValSuite.reset(v$.value)
}

const validate = function () {
  void collValSuite.validate(v$.value).then(result => {
    if (result) {
      void $f.ui.messageBox({
        caption: '成功',
        text: '验证通过',
        buttons: 'Close',
        icon: 'Succeeded'
      })
    } else {
      void $f.ui.messageBox({
        caption: '失败',
        text: '验证不通过',
        buttons: 'Close',
        icon: 'ReqErr'
      })
    }
  })
}

const assignForm = function () {
  $d.form = {
    experiences: [
      {
        company: '上海长络',
        beginDt: '2004-08-10',
        endDt: '2006-04-20',
        title: '工程师'
      },
      {
        company: '上海华依',
        beginDt: '2006-04-20',
        endDt: '2007-03-28',
        title: '工程师'
      }
    ] as Experience[]
  } as EmployeeInfo
}

const addLine = function () {
  collValSuite.addLine({
    company: '',
    beginDt: '',
    endDt: '',
    title: ''
  })
}

const removeLine = function (idx: number) {
  collValSuite.removeLine(idx)
}

const blinkLineInput = function(idx: number) {
  let count = 0;
  let line =  $d.form.experiences[idx]
  const intervalId = setInterval(() => {
    line.inputBgColor = (count % 2===0 ? 'red-2':'')
    count++;
    if (count === 8) {
      clearInterval(intervalId);  // 清除定时器
    }
  }, 100);
}

const clearLines = function () {
  collValSuite.clearLines()
}

const childComponentViewModel = ref(false)

const childCompValTest = function (){
  childComponentViewModel.value = true
}

const e$ = $f.getFieldErrStr
</script>

<style lang="sass" scoped>
.padding-slim
  padding: 1px !important
</style>
